
package com.tools.cleanmaster.ui.view.landingpage;

import android.content.Context;
import android.content.res.Resources;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.RectF;
import android.os.SystemClock;
import android.util.AttributeSet;
import android.view.View;

import com.tools.cleanmaster.R;


public class CheckMarkView extends View {

    private static final int CHECK_ANGLE = 45;
    private static final int CIRCLE_ANIMATION_TIME1 = 150;
    private static final int CIRCLE_ANIMATION_TIME2 = 125;
    private static final int CIRCLE_ANIMATION_TIME3 = 125;
    private static final int ANIMATION_TIME = 200;
    private int mLeftAnimTime, mRightAnimTime;
    private long startTime;
    private long nowTime;

    private boolean firstDrawFlag = true;
    private boolean isDrawing = false;
    private int mCenterX, mCenterY;
    private int mCheckCenterX, mCheckCenterY;
    private int bottom = 0;
    private int top = 0;
    private int mCircleRadius;
    private int mCircleAlpha;
    private int mRadius;

    private int mRoundAngle;
    private int mRoundWidth;
    private int mRoundLeftHeight;
    private int mRoundRightHeight;
    private int mOffsetX, mOffsetY;
    private Resources mResources;

    private RectF leftRect = new RectF();
    private RectF rightRect = new RectF();

    private Paint mPaint;
    private Paint mCirclePaint;

    private enum DrawStatus {
        IDLE,       // 初始状态
        CIRCLE,     // 画圆
        CHECK_MARK, // 画对号
        FINISHED    // 结束状态
    }
    private DrawStatus mStatus;

    private CheckMarkAnimListener mListener;

    public interface CheckMarkAnimListener {
        /**
         * 动画结束后回调<br>
         */
        void onCheckMarkFinished();
    }

    public void setAnimListener(CheckMarkAnimListener listener) {
        mListener = listener;
    }

    public CheckMarkView(Context context, AttributeSet attrs) {
        super(context, attrs);
        initViews();
        mStatus = DrawStatus.IDLE;
    }

    private void initViews() {
        mResources = getResources();
        leftRect = new RectF();
        rightRect = new RectF();

        mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mPaint.setColor(0xffb2f145);
        mCirclePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mCirclePaint.setColor(0xffffffff);
        mCirclePaint.setStyle(Paint.Style.STROKE);
        mCirclePaint.setStrokeWidth(mResources.getDimensionPixelSize(R.dimen.landing_page_circle_stoke_size));

        mRoundAngle = mResources.getDimensionPixelSize(R.dimen.check_mark_round_angle);
        mRoundWidth = mResources.getDimensionPixelSize(R.dimen.check_mark_round_width);
        mRoundLeftHeight = mResources.getDimensionPixelSize(R.dimen.check_mark_round_left_height);
        mRoundRightHeight = mResources.getDimensionPixelSize(R.dimen.check_mark_round_right_height);
        mOffsetX = mResources.getDimensionPixelSize(R.dimen.check_mark_offset_x);
        mOffsetY = mResources.getDimensionPixelSize(R.dimen.check_mark_offset_y);
        mCircleRadius  = mResources.getDimensionPixelSize(R.dimen.landing_page_circle_view_size)/2;

        mLeftAnimTime = (int) (mRoundLeftHeight * 1.0 / (mRoundLeftHeight + mRoundRightHeight) * ANIMATION_TIME);
        mRightAnimTime = ANIMATION_TIME - mLeftAnimTime;
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        mCenterX = w >> 1;
        mCenterY = h >> 1;

        leftRect.left = mCenterX + mOffsetX - mRoundWidth;
        leftRect.right = mCenterX + mOffsetX;
        leftRect.top = mCenterY + mOffsetY - mRoundLeftHeight;

        rightRect.left = mCenterX + mOffsetX - mRoundWidth;
        rightRect.right = mCenterX + mOffsetX;
        rightRect.bottom = mCenterY + mOffsetY;

        mCheckCenterX = mCenterX + mOffsetX;
        mCheckCenterY = mCenterY + mOffsetY;
    }

    public void startDraw() {
        isDrawing = true;
        switchDrawStatus(DrawStatus.CIRCLE);
    }

    private void switchDrawStatus(DrawStatus status) {
        mStatus = status;
        invalidate();
    }

    @Override
    protected void onDraw(Canvas canvas) {
        if (!isDrawing) {
            return;
        }
        super.onDraw(canvas);

        switch (mStatus) {
            case CIRCLE:
                nowTime = SystemClock.elapsedRealtime() - startTime;
                if (firstDrawFlag) {
                    startTime = SystemClock.elapsedRealtime();
                    firstDrawFlag = false;
                    invalidate();
                } else if (nowTime <= CIRCLE_ANIMATION_TIME1) {
                    mRadius = (int) (((nowTime) * 1.0 / CIRCLE_ANIMATION_TIME1) * mCircleRadius);
                    mCircleAlpha = (int) (((nowTime) * 1.0 / CIRCLE_ANIMATION_TIME1) * 255);
                    mCirclePaint.setAlpha(mCircleAlpha);
                    canvas.drawCircle(mCenterX, mCenterY, mRadius, mCirclePaint);
                    invalidate();
                } else if (nowTime <= CIRCLE_ANIMATION_TIME1 + CIRCLE_ANIMATION_TIME2) {
                    mCirclePaint.setAlpha(255);
                    mRadius = (int) (mCircleRadius * (1 - 0.3 * (nowTime - CIRCLE_ANIMATION_TIME1) / CIRCLE_ANIMATION_TIME2));
                    canvas.drawCircle(mCenterX, mCenterY, mRadius, mCirclePaint);
                    invalidate();
                } else if (nowTime <= CIRCLE_ANIMATION_TIME1 + CIRCLE_ANIMATION_TIME2 + CIRCLE_ANIMATION_TIME3) {
                    mRadius = (int) (mCircleRadius * (0.7 + 0.3 * (nowTime - CIRCLE_ANIMATION_TIME1 - CIRCLE_ANIMATION_TIME2) / CIRCLE_ANIMATION_TIME3));
                    canvas.drawCircle(mCenterX, mCenterY, mRadius, mCirclePaint);
                    invalidate();
                } else {
                    clearFlags();
                    switchDrawStatus(DrawStatus.CHECK_MARK);
                }
                break;
            case CHECK_MARK:
                canvas.drawCircle(mCenterX, mCenterY, mCircleRadius, mCirclePaint);

                canvas.save();
                canvas.rotate(-CHECK_ANGLE, mCheckCenterX, mCheckCenterY);
                leftRect.bottom = mCenterY + mOffsetY - mRoundLeftHeight + bottom;
                canvas.drawRect(leftRect, mPaint);
                canvas.restore();

                nowTime = SystemClock.elapsedRealtime() - startTime;
                if (firstDrawFlag) {
                    startTime = SystemClock.elapsedRealtime();
                    firstDrawFlag = false;
                    invalidate();
                } else if (nowTime <= mLeftAnimTime) {
                    bottom = (int) (((SystemClock.elapsedRealtime() - startTime) * 1.0 / mLeftAnimTime) * mRoundLeftHeight);
                    invalidate();
                } else if (nowTime <= ANIMATION_TIME) {
                    bottom = mRoundLeftHeight;
                    top = (int) (((nowTime - mLeftAnimTime) * 1.0 / mRightAnimTime) * mRoundRightHeight);
                    canvas.save();
                    canvas.translate(-mRoundAngle, mRoundAngle);
                    canvas.rotate(CHECK_ANGLE, mCheckCenterX, mCheckCenterY);
                    rightRect.top = mCenterY + mOffsetY - top;
                    canvas.drawRoundRect(rightRect, mRoundAngle, mRoundAngle, mPaint);
                    canvas.restore();
                    invalidate();
                } else if (nowTime >= ANIMATION_TIME) {
                    canvas.save();
                    canvas.translate(-mRoundAngle, mRoundAngle);
                    canvas.rotate(CHECK_ANGLE, mCheckCenterX, mCheckCenterY);
                    rightRect.top = mCenterY + mOffsetY - mRoundRightHeight;
                    canvas.drawRoundRect(rightRect, mRoundAngle, mRoundAngle, mPaint);
                    canvas.restore();
                    switchDrawStatus(DrawStatus.FINISHED);
                }
                break;
            case FINISHED:
                canvas.drawCircle(mCenterX, mCenterY, mCircleRadius, mCirclePaint);

                canvas.save();
                canvas.rotate(-CHECK_ANGLE, mCheckCenterX, mCheckCenterY);
                leftRect.bottom = mCenterY + mOffsetY;
                canvas.drawRect(leftRect, mPaint);
                canvas.restore();

                canvas.save();
                canvas.translate(-mRoundAngle, mRoundAngle);
                canvas.rotate(CHECK_ANGLE, mCheckCenterX, mCheckCenterY);
                rightRect.top = mCenterY + mOffsetY - mRoundRightHeight;
                canvas.drawRoundRect(rightRect, mRoundAngle, mRoundAngle, mPaint);
                canvas.restore();
                if (mListener != null) {
                    mListener.onCheckMarkFinished();
                }
                break;
            default:
                throw new RuntimeException("wrong status");
        }

    }

    private void clearFlags() {
        firstDrawFlag = true;
        startTime = 0;
    }

}
